import re

def fix_chinese_english_spacing(text):
    text = re.sub(r'([a-zA-Z0-9])([\u4e00-\u9fff])', r'\1 \2', text)
    text = re.sub(r'([\u4e00-\u9fff])([a-zA-Z0-9])', r'\1 \2', text)
    return text

def language_name(lang: str) -> str:
    lut = {
        'zh': 'Chinese',
        'jp': 'Japanese',
        'en': 'English',
    }
    return lut.get(lang, lang)

def detect_language(text: str, default_lang : str = 'zh', threshold : float = 0.5) -> str:
    # zh or en?
    scores = {
        'zh': 0.0,
        'jp': 0.0,
        'en': 0.0,
    }
    for c in text:
        if 0x4e00 <= ord(c) <= 0x9fff:
            scores['zh'] += 1
        elif 0x3040 <= ord(c) <= 0x30ff:
            scores['jp'] += 1.5
        elif c.isalpha():
            scores['en'] += 0.1
    threshold += 1
    for k, v in scores.items():
        if all(v > threshold * v2 for k2, v2 in scores.items() if k2 != k):
            return k
    return default_lang

def convert_japanese_romaji(text, mode='romaji'):
    # 定义罗马音和对应的假名
    hiragana = 'あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもらりるれろわがぎぐげござじずぜぞだぢづでどばびぶべぼぱぴぷぺぽん'
    katakana = 'アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモラリルレロワガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポン'
    # 创建转换表
    translation_table = str.maketrans(katakana, hiragana)
    # 转换字符串中的罗马音为假名
    text = text.translate(translation_table)
    if mode == 'romaji':
        lookup_table = {
            'あ': 'a', 'い': 'i', 'う': 'u', 'え': 'e', 'お': 'o',
            'か': 'ka', 'き': 'ki', 'く': 'ku', 'け': 'ke', 'こ': 'ko',
            'さ': 'sa', 'し': 'shi', 'す': 'su', 'せ': 'se', 'そ': 'so',
            'た': 'ta', 'ち': 'chi', 'つ': 'tsu', 'て': 'te', 'と': 'to',
            'な': 'na', 'に': 'ni', 'ぬ': 'nu', 'ね': 'ne', 'の': 'no',
            'は': 'ha', 'ひ': 'hi', 'ふ': 'fu', 'へ': 'he', 'ほ': 'ho',
            'ま': 'ma', 'み': 'mi', 'む': 'mu', 'め': 'me', 'も': 'mo',
            'ら': 'ra', 'り': 'ri', 'る': 'ru', 'れ': 're', 'ろ': 'ro',
            'や': 'ya', 'ゆ': 'yu', 'よ': 'yo',
            'わ': 'wa', 'を': 'wo', 'ん': 'n',
            'が': 'ga', 'ぎ': 'gi', 'ぐ': 'gu', 'げ': 'ge', 'ご': 'go',
            'ざ': 'za', 'じ': 'ji', 'ず': 'zu', 'ぜ': 'ze', 'ぞ': 'zo',
            'だ': 'da', 'ぢ': 'ji', 'づ': 'zu', 'で': 'de', 'ど': 'do',
            'ば': 'ba', 'び': 'bi', 'ぶ': 'bu', 'べ': 'be', 'ぼ': 'bo',
            'ぱ': 'pa', 'ぴ': 'pi', 'ぷ': 'pu', 'ぺ': 'pe', 'ぽ': 'po',
            'ん': 'n',
        }
    else:
        assert mode == 'hanzi'
        lookup_table = {
            'あ': '阿', 'い': '伊', 'う': '物', 'え': '爱', 'お': '欧',
            'か': '加', 'き': '几', 'く': '苦', 'け': '介', 'こ': '口',
            'さ': '左', 'し': '之', 'す': '寸', 'せ': '世', 'そ': '曾',
            'た': '塔', 'ち': '七', 'つ': '磁', 'て': '天', 'と': '投',
            'な': '那', 'に': '你', 'ぬ': '奴', 'ね': '内', 'の': '诺',
            'は': '哈', 'ひ': '比', 'ふ': '不', 'へ': '部', 'ほ': '保',
            'ま': '玛', 'み': '米', 'む': '木', 'め': '美', 'も': '莫',
            'ら': '拉', 'り': '利', 'る': '露', 'れ': '类', 'ろ': '搂',
            'や': '呀', 'ゆ': '由', 'よ': '哟',
            'わ': '瓦', 'を': '卧', 'ん': '恩',
            'が': '我', 'ぎ': '义', 'ぐ': '古', 'げ': '外', 'ご': '钩',
            'ざ': '座', 'じ': '极', 'ず': '字', 'ぜ': '是', 'ぞ': '奏',
            'だ': '达', 'ぢ': '及', 'づ': '组', 'で': '得', 'ど': '都',
            'ば': '八', 'び': '比', 'ぶ': '补', 'べ': '被', 'ぼ': '波',
            'ぱ': '爬', 'ぴ': '披', 'ぷ': '铺', 'ぺ': '陪', 'ぽ': '破',
            'ん': '嗯',
        }
    # 转换字符串中的假名为罗马音
    converted_text = ''
    for c in text:
        if c in lookup_table:
            converted_text += lookup_table[c]
        else:
            converted_text += c
    return converted_text

def convert_puncation_marks(text, force_split=False):
    # 定义全角标点和对应的半角标点
    full_width_punctuation = '，、。！？；：“”‘’（）【】{}《》～'
    half_width_punctuation = ',,.!?;:""\'\'()[]{}<>~'
    if force_split:
        lines = re.split('[\\n' + re.escape(full_width_punctuation + half_width_punctuation) + ']', text)
        return [line for line in (line.strip() for line in lines) if line]
    # 创建转换表
    translation_table = str.maketrans(full_width_punctuation, half_width_punctuation)
    # 转换字符串中的全角标点为半角标点
    converted_text = text.translate(translation_table)
    return converted_text

def simplify_query(query):
    query = query.lower()
    query = query.replace(' ', '')
    query = query.replace('-', '')
    query = convert_puncation_marks(query)
    query = convert_japanese_romaji(query)
    return query

def fuzzy_search(musics, query):
    query = simplify_query(query)
    musics = [simplify_query(music) for music in musics]
    results = {}
    for i, name in enumerate(musics):
        if query in name:
            results[i] = 10000
    if len(results) <= 1:
        qset = set(query)
        for i, name in enumerate(musics):
            count = 0
            for c in name:
                if c in qset:
                    qset.remove(c)
                    count += 1
            if count >= 3:
                results.setdefault(i, count)
                break
    if len(results) <= 1:
        qset = set(query)
        for i, name in enumerate(musics):
            count = 0
            for c in name:
                if c in qset:
                    qset.remove(c)
                    count += 1
            if count >= 2:
                results.setdefault(i, count // 2)
                break
    if len(results) <= 1:
        for i, name in enumerate(musics):
            count = 0
            for c in name:
                if c in query:
                    results.setdefault(i, 1)
                    break
    results = sorted(results.items(), key=lambda x: x[1], reverse=True)
    results = [i[0] for i in results]
    return results
